﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.Net.Sockets;
using System.IO;
using System.Threading;
using System.Diagnostics;

namespace Barockoco_Chat_Client
{    
    public partial class Client : Form
    {
        private string[] Resolver(string DnsName)
        {
            System.Net.IPHostEntry IHE = Dns.GetHostEntry(DnsName);
            string[] ret = new string[IHE.AddressList.Length];
            for (int i = 0; i < IHE.AddressList.Length; i++)
                ret[i] = IHE.AddressList[i].ToString();
            return ret;
        }

        //will hold the user name
        private string UserName = "Benutzername";
        private StreamWriter swSender;
        private StreamReader srReceiver;
        private TcpClient tcpServer;
        //needed to update the form with messages from another thread
        private delegate void UpdateLogCallback(string strMessage);
        //needed to set the form as "disconnected" from another thread
        private delegate void CloseConnectionCallback(string strReason);
        private Thread thrMessaging;
        private IPAddress ipAddr;
        private bool Connected;

        private void Client_Load(object sender, EventArgs e) { 
        
        }

        public Client()
        {
            // On application exit, don't forget to disconnect first
            Application.ApplicationExit += new EventHandler(OnApplicationExit);
            InitializeComponent();
            textUserName.Text = UserName;
            textUserName.Focus();
            textIpAdress.Enabled = false;
            textIpAdress.Text = "192.168.178.100";
            LocationComboBox.Enabled = false;
            LocationComboBox.SelectedIndex = 10;
            textUserName.Enabled = true;
            textMessage.Enabled = false;
            buttonMessageSend.Enabled = false;
            buttonConnect.Text = "Connect";
            datevExportButton.Enabled = false;
        }

        public void OnApplicationExit(object sender, EventArgs e) { 
            if(Connected==true){
                // Closes the connections, streams, etc.
                Connected = false;
                swSender.Close();
                srReceiver.Close();
                tcpServer.Close();
            }
        }
                
        /*
        private void textMessage_Keypress(object sender, KeyPressEventArgs e)
        {
            //if the Key is "Enter" then call the send function
            if (e.KeyChar == (char)13)
            {
                SendMessage();
            }
        }
        */
        
        private void textMessage_KeyDown(object sender, KeyEventArgs e)
        {
            //MessageBox.Show("Ich bin in der Schleife");
            if (e.KeyCode == Keys.Enter)
            {
                //MessageBox.Show("Enter gedrückt");
                SendMessage();
            }
            else {
                //Wenn irgendwas außer Enter gedrückt...
            }
        }
        
        // Closes a current connection
        private void CloseConnection(string Reason)
        {
            // Show the reason why the connection is ending
            txtLog.AppendText(Reason + "\r\n");
            // Enable and disable the appropriate controls on the form
            textIpAdress.Enabled = false;
            textUserName.Enabled = true;
            textMessage.Enabled = false;
            buttonMessageSend.Enabled = false;
            LocationComboBox.Enabled = false;
            datevExportButton.Enabled = false;
            buttonConnect.Text = "Connect";
            
            //set the connect field to true to let the user know hes connected now
            checkBoxConnectState.Checked = false;

            // Close the objects
            Connected = false;
            swSender.Close();
            srReceiver.Close();
            tcpServer.Close();
        }
        
        private void FocusOnUserName(object sender, KeyEventArgs e) {
            if (e.KeyCode == Keys.Enter)
            {
                textUserName.Focus();
            }
            else { }
        }

        private void StarteVerbindungMitEnter(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
            {
                //MessageBox.Show("Enter gedrückt");
                InitializeConnection();
            }
            else
            {
                //Wenn irgendwas außer Enter gedrückt...
            }
        }

        private void InitializeConnection()
        {
            // Parse the IP address from the TextBox into an IPAddress object
            try
            {
                ipAddr = IPAddress.Parse(textIpAdress.Text);
            }
            catch (Exception){
                try
                {
                    
                    string[] parsedip = Resolver(textIpAdress.Text);
                    ipAddr = IPAddress.Parse(parsedip[0]);
                }
                catch (Exception) { 
                    MessageBox.Show("Die eingegebene Serveradresse ist nicht gültig! \n Ich habe es unter "+ipAddr+" versucht.." );
                }
            }
            // Start a new TCP connection to the chat server
            tcpServer = new TcpClient();

            try
            {
                tcpServer.Connect(ipAddr, 1986);
            }
            catch (Exception){
                
            } 
            // Helps us track whether we're connected or not
            Connected = true;

            // Prepare the form
            UserName = textUserName.Text;
            
            // Disable and enable the appropriate fields
            textIpAdress.Enabled = false;
            textUserName.Enabled = false;
            LocationComboBox.Enabled = true;
            textMessage.Enabled = true;
            buttonMessageSend.Enabled = true;
            //Datevexport ist nur als Buchhalter möglich!
            if (UserName == "Buchhaltung")
            {
                datevExportButton.Enabled = true;
            }
            buttonConnect.Text = "Disconnect";

            // Send the desired username to the server
            try
            {
                swSender = new StreamWriter(tcpServer.GetStream());
                swSender.WriteLine(textUserName.Text);
                swSender.Flush();
            
                // Start the thread for receiving messages and further communication
                thrMessaging = new Thread(new ThreadStart(ReceiveMessages));
                thrMessaging.Start();

                //set the connect field to true to let the user know hes connected now
                checkBoxConnectState.Checked = true;
            }
            catch (Exception e)
            {
                MessageBox.Show("Der Benutzername konnte dem Server nicht mitgeteilt werden.\nSie sind wahrscheinlich nicht mit dem Server verbunden.");
                Console.WriteLine(e);
            }
        }
                
        private void ReceiveMessages()
        {
            // Receive the response from the server
            srReceiver = new StreamReader(tcpServer.GetStream());
            // If the first character of the response is 1, connection was successful
            string ConResponse = srReceiver.ReadLine();
            // If the first character is a 1, connection was successful
            if (ConResponse[0] == '1')
            {
                // Update the form to tell it we are now connected
                this.Invoke(new UpdateLogCallback(this.UpdateLog), new object[] { "Erfolgreich mit dem Server verbunden!" });
            }

            else // If the first character is not a 1 (probably a 0), the connection was unsuccessful
            {

                string Reason = "Nicht verbunden: ";
                // Extract the reason out of the response message. The reason starts at the 3rd character
                Reason += ConResponse.Substring(2, ConResponse.Length - 2);
                // Update the form with the reason why we couldn't connect
                this.Invoke(new CloseConnectionCallback(this.CloseConnection), new object[] { Reason });
                // Exit the method
                return;
            }

            // While we are successfully connected, read incoming lines from the server
            while (Connected == true)
            {
                try
                {
                    // Show the messages in the log TextBox
                    this.Invoke(new UpdateLogCallback(this.UpdateLog), new object[] { srReceiver.ReadLine() });
                }
                catch { }
            }
        }
        
        // This method is called from a different thread in order to update the log TextBox
        private void UpdateLog(string strMessage)
        {
            // Append text also scrolls the TextBox to the bottom each time
            txtLog.AppendText(strMessage + "\r\n");
        }

        // Sends the message typed in to the server
        private void SendMessage()
        {
            try
            {
                if (textMessage.Lines.Length == 1)
                {
                    swSender.WriteLine(textMessage.Text);
                    swSender.Flush();
                    textMessage.Lines = null;
                }
                textMessage.Text = "";
            }
            catch (Exception)
            {
                MessageBox.Show("Beim Versuch eine Nachricht zu senden ist ein Fehler aufgetreten! \n" +
                "Sollten Sie diese Nachricht öfters sehen, Kontaktieren Sie Phenyll!");
            }
        }

        // Sends the QuickMessage bound to string QuickMessage to the server
        private void SendQuickMessage(string QuickMessage)
        {
            try
            {
                swSender.WriteLine(QuickMessage);
                swSender.Flush();
            }
            catch (Exception) { 
                MessageBox.Show("Beim Versuch eine Schnellnachricht zu senden ist ein Fehler aufgetreten! \n"+ 
                "Sollten Sie diese Nachricht öfters sehen, Kontaktieren Sie Phenyll!"); 
            }
        }

        private void buttonConnect_Click(object sender, EventArgs e)
        {
            // If we are not currently connected but awaiting to connect
            if (Connected == false)
            {
                // Initialize the connection
                InitializeConnection();
            }
            else // We are connected, thus disconnect
            {
                CloseConnection("Verbindgung auf Verlangen des Benutzers unterbrochen.");
            }
        }

        private void buttonMessageSend_Click(object sender, EventArgs e)
        {
            // test:  MessageBox.Show("Barockoco");
            SendMessage();
        }

        private void buttonQuickKaffee_Click(object sender, EventArgs e)
        {
            SendQuickMessage("Bring mir bitte Kaffee in den Raum:  " + LocationComboBox.SelectedItem + ", Danke!");
        }

        private void button1_Click(object sender, EventArgs e)
        {
            SendQuickMessage("Bring mir bitte Sekt in den Raum:  "+LocationComboBox.SelectedItem+", Danke!");
        }

        private void LocationComboBox_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (Connected == true)
            {
                SendQuickMessage(UserName + " ist jetzt in/im " + LocationComboBox.SelectedItem);
            }
            else { }
        }

        private void datevExportButton_Click(object sender, EventArgs e)
        {
            if (Connected == true)
            {
                SendQuickMessage("/admin;Lexware;begindate=" + dateTimePicker1.Value.ToString("dd.MM.yyyy") + ";enddate=" + dateTimePicker2.Value.ToString("dd.MM.yyyy"));
                //datacopy("","");
            }
            else 
            {
                MessageBox.Show("Sie sind nich mit dem Server verbunden, bitte Verbinden Sie auf dem Tab Einstellungen, links oben.");
            }
        }
        
        public static void datacopy(string from, string to) 
        {
            if (from == "") 
            {
                FolderBrowserDialog fbd = new FolderBrowserDialog();
                fbd.ShowDialog();
                from = fbd.SelectedPath;
            }
            if(to == "")
            {
                FolderBrowserDialog fbd = new FolderBrowserDialog();
                fbd.ShowDialog();
                to = fbd.SelectedPath;
            }
            try
            {
                File.Copy(from, to);
            }
            catch (Exception e)
            {
                MessageBox.Show(e.Message);
            }
        }

        private void MapNetworkDrive(string uri, string unc)
        {
            try
            {
                ProcessStartInfo info = new ProcessStartInfo("net", "use " + uri + " " + unc);//net use x: \\milan\daten mitarbeiter
                info.UseShellExecute = false;
                info.WindowStyle = ProcessWindowStyle.Hidden;
                Process.Start(info);
            }
            catch (Exception e) 
            {
                MessageBox.Show(e.Message+"\n Bitte wenden Sie sich an den Administrator unter 0170 - 855 31 15");
            }
        }

        private void buttonNetUseX_Click(object sender, EventArgs e)
        {
            MapNetworkDrive("X:", "\\\\milan\\daten");
            OpenExplorer(@"X:\");
        }

        private static void OpenExplorer(string path)
        {
            if (Directory.Exists(path))
                Process.Start("explorer.exe", path);
        }

        private void buttonShowFolderBuchhaltung_Click(object sender, EventArgs e)
        {
            OpenExplorer(@"X:\Buchhaltung\");
        }

        private void buttonExportMorph_Click(object sender, EventArgs e)
        {
            MessageBox.Show("Diese Funktion ist derzeit deaktiviert. \n\n Sollten Sie dennoch den Export ändern wollen, kontaktieren Sie den Administrator unter \n 0170-8553115");
            //OpenFileDialog openFileDialogExportMorph = new OpenFileDialog();
            //openFileDialogExportMorph.Title = "Exportdatei wählen:";
            //openFileDialogExportMorph.FileName = @"X:\Buchhaltung\Lexware\";       // Vorgabe Pfad (und danach der gewählte Pfad)
            //DialogResult objResult = openFileDialogExportMorph.ShowDialog(this);
            //if (objResult == DialogResult.OK)
            //{
            //    //MessageBox.Show("Neuer Pfad : " + openFileDialogExportMorph.FileName);
            //    Form DataMorph = new DataMorph(openFileDialogExportMorph.FileName);
            //    DataMorph.Show();
            //}
            //else
            //{
            //    //MessageBox.Show("Es wurde abgebrochen!");
            //}
        }
    }
}
